package com.fzy.common.file;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.imageio.ImageIO;

import com.jhlabs.image.CropFilter;
import com.jhlabs.image.ThresholdFilter;

public class ImageUtil {
    private ImageUtil() {
    }
    /**
     * 给图片加水印
     */
    @SuppressWarnings("unused")
    public static BufferedImage createWaterMark(BufferedImage img, BufferedImage watermark, float alpha,
                                                float percentSize,
                                                int border) {

        int newWatWidth = Math.round(percentSize * img.getWidth());

        int newWatHeight = Math.round((newWatWidth / (1.0f * watermark.getWidth())) * watermark.getHeight());

        int watOffsetX = img.getWidth() - newWatWidth - border;
        int watOffsetY = img.getHeight() - newWatHeight - border;

        BufferedImage resizedThumbnail = new BufferedImage(newWatWidth, newWatHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = resizedThumbnail.createGraphics();

        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2D.drawImage(watermark, 0, 0, newWatWidth, newWatHeight, null);
        Graphics2D g = img.createGraphics();

        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        g.drawImage(resizedThumbnail, watOffsetX, watOffsetY, null);

        resizedThumbnail.flush();
        g.dispose();
        return resizedThumbnail;
    }


    /**
     * 图片上合成文字
     *
     * @param srcImageFile        原图片
     * @param descImageFile       目标图片
     * @param color               文字颜色
     * @param alphaCompositeValue 透明度
     * @param textString          文字
     * @param font                字体
     * @param boldStyle           加粗模式
     * @param fontSize            字体大小
     * @param isTextVertical      是否竖排
     * @param padLeft             左边距
     * @param padTop              上边距
     * @throws IOException
     */
    public static void compositeText(String srcImageFile, String descImageFile, int color, float alphaCompositeValue,
                                     String textString, String font, int boldStyle, int fontSize, boolean isTextVertical, int padLeft, int padTop)
            throws IOException {

        int ascent, descent, width, height, charWidth, charHeight, statrX, statrY;
        FontMetrics fontMetrics;

        BufferedImage image = ImageIO.read(new File(srcImageFile));

        // Graphics g = image.getGraphics();
        Graphics g = image.getGraphics();

        g.setColor(new Color(0, 0, 0));
        g.setFont(new Font(font, boldStyle, fontSize));

        // Obtain a Graphics2D object
        Graphics2D g2 = (Graphics2D) g;
        // Set the rendering quality.
        // g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // g2.transform(AffineTransform.getTranslateInstance(14, 16/4));
        // g2.setFont(new Font(ft,Font.PLAIN, 16));
        g2.setPaint(new Color(color));
        // set compositing rule with transparency
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaCompositeValue));

        fontMetrics = g2.getFontMetrics(); // 取得FontMetrics类实体
        ascent = fontMetrics.getAscent(); // 取得Ascent
        charHeight = fontMetrics.getHeight(); // 取得Height
        descent = fontMetrics.getDescent(); // 取得Descent
        width = fontMetrics.stringWidth(textString); // 取得字符串宽度
        charWidth = width / textString.length();
        height = charHeight * textString.length(); // 取得Height

        if (!isTextVertical) {// 横排
            // 多行处理
            if (width > (image.getWidth() - padLeft * 2)) {
                int lineStringLength = (image.getWidth() - padLeft * 2) / charWidth;
                int lines = (int) Math.ceil(new Float(textString.length()) / new Float(lineStringLength));
                int startYOffet = (image.getHeight() - charHeight * lines) / 2 + padTop;
                for (int i = 0; i < lines; i++) {
                    int endIndex = (i + 1) * lineStringLength;
                    if (endIndex > textString.length()) {
                        endIndex = textString.length();
                    }
                    String drawString = textString.substring(i * lineStringLength, endIndex);
                    statrX = (image.getWidth() - charWidth * lineStringLength) / 2 + padLeft;
                    statrY = startYOffet + charHeight * i + ascent;
                    g2.drawString(drawString, statrX, statrY);
                }

            } else {
                // 单行处理
                // 计算置中坐标
                statrX = (image.getWidth() - width) / 2;
                statrY = (image.getHeight() - (ascent + descent)) / 2 + ascent;
                g2.drawString(textString, statrX, statrY);
            }
        } else {// 竖排
            // 多列处理
            if (height > (image.getHeight() - padTop * 2)) {
                int lineStringLength = (image.getHeight() - padTop * 2) / charHeight;
                int lines = (int) Math.ceil(new Float(textString.length()) / new Float(lineStringLength));
                int startYOffet = (image.getHeight() - charHeight * lineStringLength) / 2 + padTop;
                for (int i = 0; i < lines; i++) {
                    int endIndex = (i + 1) * lineStringLength;
                    if (endIndex > textString.length()) {
                        endIndex = textString.length();
                    }
                    String drawString = textString.substring(i * lineStringLength, endIndex);

                    statrX = (image.getWidth() - charWidth * lines) / 2 + i * charWidth;

                    for (int j = 0; j < drawString.length(); j++) {
                        String charDrawString = drawString.substring(j, j + 1);
                        statrY = startYOffet + charHeight * j + ascent;
                        g2.drawString(charDrawString, statrX, statrY);
                    }
                }

            } else {// 单列处理
                int lines = textString.length();
                // 计算置中坐标
                statrX = (image.getWidth() - charWidth) / 2;
                int startYOffet = (image.getHeight() - charHeight * lines) / 2;

                for (int i = 0; i < lines; i++) {
                    String drawString = textString.substring(i, i + 1);
                    width = fontMetrics.stringWidth(drawString); // 取得字符串宽度
                    statrY = startYOffet + charHeight * i + ascent;
                    g2.drawString(drawString, statrX, statrY);
                }
            }
        }

        g2.dispose();
        ImageIO.write(image, "jpg", new File(descImageFile));
    }


    /**
     * 对上传图片进行缩放 (缩放后图片宽度指定 高度按比例调整)
     *
     * @param srcImageFile  源图像文件地址
     * @param descImageFile 缩放后的图像地址
     * @param zoomWidth     缩放后图片宽度
     * @throws IOException
     */
    public static void scale(String srcImageFile, String descImageFile, int zoomWidth) throws IOException {
        BufferedImage src = ImageIO.read(new File(srcImageFile)); // 读入文件
        int width = src.getWidth(); // 得到源图宽
        int height = src.getHeight(); // 得到源图长

        int zoomHeight = (height * zoomWidth) / width;//缩放后图片高度
        Image image = src.getScaledInstance(zoomWidth, zoomHeight, Image.SCALE_DEFAULT);
        BufferedImage tag = new BufferedImage(zoomWidth, zoomHeight, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.drawImage(image, 0, 0, null); // 绘制缩小后的图
        g.dispose();
        ImageIO.write(tag, "JPEG", new File(descImageFile));// 输出到文件流
    }

    /**
     * 对上传图片进行切割
     *
     * @param srcImageFile  源图像地址
     * @param descImageFile 切片目标文件夹
     * @param x             坐标x
     * @param y             坐标y
     * @param width         目标切片宽度
     * @param height        目标切片高度
     * @throws IOException
     */
    public static void corp(String srcImageFile, String descImageFile, int x, int y, int width, int height)
            throws IOException {

        BufferedImage image = ImageIO.read(new File(srcImageFile));

        if (width == 0) {
            width = image.getWidth();
        }
        if (height == 0) {
            height = image.getHeight();
        }

        BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		CropFilter filter = new CropFilter(x, y, width, height);
		filter.filter(image, image2);
        ImageIO.write(image2, "jpg", new File(descImageFile));
    }


    /**
     * 切完彩色图片转为 黑白 => 指定大小,黑色变指定色(金色)
     *
     * @param srcImageFile
     * @param descImageFile
     * @throws IOException
     */
    public static void gray(String srcImageFile, String descImageFile, int color, int tagWidth, int tagHeight) throws IOException {
        BufferedImage srcImage = ImageIO.read(new File(srcImageFile));

        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        ColorConvertOp op = new ColorConvertOp(cs, null);
        srcImage = op.filter(srcImage, null);

        BufferedImage tempImage = new BufferedImage(srcImage.getWidth(), srcImage.getHeight(), BufferedImage.TYPE_INT_RGB);

        ThresholdFilter filter = new ThresholdFilter();
        filter.setBlack(color);
        filter.filter(srcImage, tempImage);

        Image image = tempImage.getScaledInstance(tagWidth, tagHeight, Image.SCALE_DEFAULT);
        BufferedImage tag = new BufferedImage(tagWidth, tagHeight, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.drawImage(image, 0, 0, null); // 绘制缩小后的图
        g.dispose();
        ImageIO.write(tag, "jpg", new File(descImageFile));
    }

    /**
     * 获取当前日期 作为文件夹目录名
     *
     * @param date
     */
    public static String makeFolderName(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        String monthPreStr = (gc.get(GregorianCalendar.MONTH) < 9 ? "0" : "");
        String dayPreStr = (gc.get(GregorianCalendar.DATE) < 10 ? "0" : "");
        return new String(gc.get(GregorianCalendar.YEAR) + monthPreStr + (gc.get(GregorianCalendar.MONTH) + 1)
                + dayPreStr + gc.get(GregorianCalendar.DATE));
    }
}
